package com.ws.innerclass;

import com.sun.corba.se.impl.resolver.SplitLocalResolverImpl;

/*
类的内部成员之五：内部类
1.Java中允许将一个类A声明在另一个类B中，则类A就是内部类，类B称为外部类

2.内部类的分类：成员内部类(静态，非静态) VS 局部内部类(方法内、代码块内、构造器内)

3.成员内部类：
    一方面：作为外部类的成员：
        > 调用外部类的结构
        > 可以被static修饰
        > 可以被4种不同的权限修饰

    另一方面：作为一个类
        > 类内可以定义属性、方法、构造器等
        > 可以被 final 修饰，表示此类不能被继承（不使用final修饰可以被继承）
        > 可以被abstract修饰，表示此类不能被实例化

4.关注如下的3各问题
    4.1 如何实例化成员内部类的对象
    4.2 如何在成员内部类中区分调用外部类的结构
    4.3 开发中局部内部类的使用  见 InnerClassTest1
 */
public class InnerClassTest {
    public static void main(String[] args) {

        //如何实例化成员内部类的对象
        //创建BB实例（静态的成员内部类）
        Person.BB bb = new Person.BB();
        bb.byName();

        //创建BB2实例（非静态的成员内部类）
        //Person.BB2 bb2 = new Person.BB2();//错误
        Person person = new Person();
        Person.BB2 bb2 = person.new BB2();
        bb2.byName();
        bb2.display("形参Name");
        Person.BB2 bb3 = new Person().new BB2();
    }
}

class Person {

    String name = "PersonName";
    int age;
    private String sex;
    public void eat() {
        System.out.println("人：吃饭");
    }

    //静态成员内部类
    static class BB {
        String name;//成员变量
        public BB() {}//构造器
        public void byName() {
            System.out.println("方法BB");
            //eat();  //静态不能加载非静态结构
        }
    }

    //非静态成员内部类
    class BB2 {
        String name = "BB2Name";//成员变量
        public BB2() {}//构造器
        public void byName() {
            System.out.println("方法BB2");
            eat();
            Person.this.eat();//完整的调用
        }
        //如何在成员内部类中区分调用外部类的结构
        public void display(String name) {
            System.out.println(name);//方法的形参
            System.out.println(this.name);//调用本类中的name
            System.out.println(Person.this.name);//调用Person类中的name
            System.out.println(age);
        }
    }


    public void method() {
        this.age = 3;
        int age = 10;
        //局部内部类
        class AA {
            int a = 1;
            int b = Person.this.age;
            String sex = Person.this.sex;
        }

        AA aa = new AA();
        System.out.println(aa.a);
    }

    {
        //局部内部类
        class AA {
        }
    }


}
